#ifndef __GLF_CORE_SYNCEVENT_H_INCLUDED__
#define __GLF_CORE_SYNCEVENT_H_INCLUDED__

#include <glf/config.h>
#include <glf/config/platform.h>

// The Sync Event Concept class here is only used for documentation purpose.
// 
// In debug, specific platform implementation derived from this class to make sure the API is consistent
// accross platform, but it is not derived from in release.
//
// DO NOT USE THIS CLASS FOR POLYPHORMISM, IT IS NOT ITS ROLE.

namespace glf {

	//! Struct use to defer the initialization of the sync event object.
	struct DeferEvent
	{
	};

	// Const variable use to defer the initialization of the sync event object.
	static const DeferEvent deferEvent = {};

	//! An event object used for synchronization.
	/** Create an unnamed event object. The object initial state is nonsignaled, and it will
	 *  auto-reset when a waiting thread is released.
	 */
	class SyncEventConcept
	{
	public:
		//! Creante & Initializes the event object.
		SyncEventConcept() {}

		//! Create the event object without initializing it.
		SyncEventConcept(DeferEvent) {}
		
		//! Release all ressources allocated by the event object.
		virtual ~SyncEventConcept() {}

		//! Initializes the event object.
		/** Can only be cassed on an uninitiliazed event object created with 
		 *  the defered parameter.
		 */
		virtual void Init() = 0;

		//! Sets the specified event object to the signaled state.
		/** The state will return to unsignaled after a call to Wait() */
		virtual void Signal() = 0;

		//! Permanately set the object to the signaled state.
		virtual void Set() = 0;

		//! Remove the permanately set signaled state.
		virtual void Reset() = 0;

		//! Waits until the event is in the signaled state.
		/** The function returns when the event is in the signaled state, or when the 
		 *  time-out interval elapses.
		 *
		 *  \param duration As per GLF convention, a value of 0 means inifinite wait
		 *                  time.
		 *  \return If the event became signaled, the return value is true.
		 */
		virtual bool Wait(unsigned long duration = 0) = 0;
	};

} // end namespace glf

#define GLFi_SYNCEVENT_HEADER(path, api)	GLF_TOSTRING(GLFi_SYNCEVENT_HEADER2(path,api))
#define GLFi_SYNCEVENT_HEADER2(path, api)	GLFi_SYNCEVENT_HEADER3(path,api)
#define GLFi_SYNCEVENT_HEADER3(path, api)	path##_##api##_.h

#if defined(SN_TARGET_PSP2)
#include <glf/core/syncEvent_psp2_.h>
#else
#	include GLFi_SYNCEVENT_HEADER(syncEvent, GLF_API_THREAD)
#endif

#endif // __GLF_CORE_SYNCEVENT_H_INCLUDED__
